package config

import (
	"github.com/spf13/viper"
	"path"
	"runtime"
)

type DB struct {
	Host     string `json:"host" yaml:"host"`
	Port     string `json:"port" yaml:"port"`
	User     string `json:"user" yaml:"user"`
	Password string `json:"password" yaml:"password"`
	Name     string `json:"name" yaml:"name"`
}

type Blog struct {
	Server Server
}
type Server struct {
	Name    string `json:"name" yaml:"name"`
	Host    string `json:"host" yaml:"host"`
	GRPC    GRPC
	HTTP    HTTP
	Metrics Metrics
}

type HTTP struct {
	Port string `json:"port" yaml:"port"`
}

type DTM struct {
	Server Server
}

type GRPC struct {
	Port string `json:"port" yaml:"port"`
}

type Metrics struct {
	Port string `json:"port" yaml:"port"`
}

type Permission struct {
	DB     DB
	Server Server
}
type Dict struct {
	DB     DB
	Server Server
}
type Auth struct {
	Server Server
	DB     DB
}
type JWT struct {
	SigningKey  string `mapstructure:"signing-key" json:"signingKey" yaml:"signing-key"`    // jwt签名
	ExpiresTime int64  `mapstructure:"expires-time" json:"expiresTime" yaml:"expires-time"` // 过期时间
	BufferTime  int64  `mapstructure:"buffer-time" json:"bufferTime" yaml:"buffer-time"`    // 缓冲时间
	Issuer      string `mapstructure:"issuer" json:"issuer" yaml:"issuer"`                  // 签发者
}

type Post struct {
	DB     DB
	Server Server
}
type Comment struct {
	DB     DB
	Server Server
}
type Menu struct {
	DB     DB
	Server Server
}

type Config struct {
	DTM        DTM
	Blog       Blog
	Permission Permission
	Dict       Dict
	Post       Post
	Comment    Comment
	Auth       Auth
	Menu       Menu
	JWT        JWT
}

func Load(path string) (*Config, error) {
	if path == "" {
		path = GetPath()
	}
	//viper 读取配置文件
	viper.SetConfigFile(path)
	err := viper.ReadInConfig()
	if err != nil {
		return nil, err
	}
	conf := &Config{}
	err = viper.Unmarshal(conf)
	if err != nil {
		return nil, err
	}

	return conf, nil
}

func GetPath() string {
	dir := getSourcePath()
	return dir + "/../../../configs/config.yaml"
}

func getSourcePath() string {
	_, filename, _, _ := runtime.Caller(1)
	return path.Dir(filename)
}
